package com.spring.bean.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;


/**
 *@Conditional注解表示在满足某种条件后才初始化一个bean或者启用某些配置。
 * 它一般用在由@Component、@Service、@Configuration等注解标识的类上面，或者由@Bean标记的方法上。
 * 如果一个@Configuration类标记了@Conditional，则该类中所有标识了@Bean的方法和@Import注解导入的相关类将遵从这些条件。
 *
 *
 * Spring Boot定义了很多有趣的条件，并把他们运用到了配置类上，这些配置类构成了Spring Boot的自动配置的基础。
 * Spring Boot运用条件化配置的方法是：定义多个特殊的条件化注解，并将它们用到配置类上。
 * 下面列出了Spring Boot提供的部分条件化注解：
 *
 * 条件化注解	                    配置生效条件
 * @ConditionalOnBean               配置了某个特定bean
 * @ConditionalOnMissingBean        没有配置特定的bean
 * @ConditionalOnClass              Classpath里有指定的类
 * @ConditionalOnMissingClass       Classpath里没有指定的类
 * @ConditionalOnExpression         给定的Spring Expression Language表达式计算结果为true
 * @ConditionalOnJava               Java的版本匹配特定指或者一个范围值
 * @ConditionalOnProperty           指定的配置属性要有一个明确的值
 * @ConditionalOnResource           Classpath里有指定的资源
 * @ConditionalOnWebApplication     这是一个Web应用程序
 * @ConditionalOnNotWebApplication  这不是一个Web应用程序
 *
 *
 * 在Spring里可以很方便的编写你自己的条件类，
 * 所要做的就是实现Condition接口，并覆盖它的matches()方法。举个例子，
 * 下面的简单条件类表示只有在Classpath里存在JdbcTemplate类时才生效：
 * */
public class JdbcTemplateCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        try {
            context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }
}
